home *** CD-ROM | disk | FTP | other *** search
/ Experimental BBS Explossion 3 / Experimental BBS Explossion III.iso / c / modex104.zip / C_UTILS.ASM < prev    next >
Assembly Source File  |  1993-05-14  |  9KB  |  406 lines

  1. ;=======================================================
  2. ;===  C_UTILS.ASM  - Asm Utilities for C/C++         ===
  3. ;=======================================================
  4.  
  5.     PAGE    255, 132
  6.  
  7.     .MODEL Medium
  8.     .286
  9.  
  10.     ; ==== MACROS ====
  11.  
  12.     ; macros to PUSH and POP multiple registers
  13.  
  14. PUSHx MACRO R1, R2, R3, R4, R5, R6, R7, R8
  15.     IFNB <R1>
  16.         push    R1                ; Save R1
  17.         PUSHx    R2, R3, R4, R5, R6, R7, R8
  18.     ENDIF
  19. ENDM
  20.  
  21. POPx MACRO R1, R2, R3, R4, R5, R6, R7, R8
  22.     IFNB <R1>
  23.         pop        R1                ; Restore R1
  24.         POPx    R2, R3, R4, R5, R6, R7, R8
  25.     ENDIF
  26. ENDM
  27.  
  28.     ; Macro to Clear a Register to 0
  29.  
  30. CLR MACRO Register
  31.     xor        Register, Register        ; Set Register = 0
  32. ENDM
  33.  
  34.     ; Macros to Decrement Counter & Jump on Condition
  35.  
  36. LOOPx MACRO Register, Destination
  37.     dec        Register                ; Counter--
  38.     jnz        Destination                ; Jump if not 0
  39. ENDM
  40.  
  41. LOOPjz MACRO Register, Destination
  42.     dec        Register                ; Counter--
  43.     jz        Destination                ; Jump if 0
  44. ENDM
  45.  
  46.  
  47.     ; ==== General Constants ====
  48.  
  49.     False    EQU    0
  50.     True    EQU    -1
  51.     nil        EQU 0
  52.  
  53.     b        EQU    BYTE PTR
  54.     w        EQU    WORD PTR
  55.     d        EQU    DWORD PTR
  56.     o        EQU    OFFSET
  57.     f        EQU FAR PTR
  58.     s        EQU    SHORT
  59.     ?x4        EQU <?,?,?,?>
  60.     ?x3        EQU <?,?,?>
  61.  
  62.  
  63.     .Data
  64.  
  65.     EVEN
  66.  
  67. RND_Seed    DW    7397, 29447, 802
  68. RND_Mult    DW    179, 183, 182
  69. RND_ModV    DW    32771, 32779, 32783
  70.  
  71. CR_LF        DB    13, 10            ; the CRLF data
  72.  
  73.     .Code
  74.  
  75. ;===========================================
  76. ;void far pascal dos_print  (far char *Text)
  77. ;===========================================
  78. ;
  79. ; - Print Text Directly to DOS console w/ CR/LF
  80. ;
  81.  
  82.     PUBLIC    DOS_PRINT
  83.  
  84. DP_Stack    STRUC
  85.                 DW    ?x4    ; DI, SI, DS, BP
  86.                 DD    ?    ; Caller
  87.     DP_Text        DD    ?    ; Far Address of Text to print
  88. DP_Stack    ENDS
  89.  
  90.  
  91. DOS_PRINT     PROC     FAR
  92.                
  93.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  94.     mov        BP, SP                ; Set up Stack Frame
  95.  
  96.     lds     DX, [BP].DP_Text    ; Get Addr of Text$ descriptor
  97.  
  98.     ; Compute Length of string
  99.  
  100.     CLR        CX                    ; Length = 0
  101.     mov        SI, DX                ; DS:SI = String data
  102.  
  103. @@DP_Scan_it:
  104.     
  105.     cmp        b [SI], 0            ; Null Byte found?
  106.     je        @@DP_Got_Len        ; exit loop if so
  107.  
  108.     inc        CX                    ; Len++
  109.     inc        SI                    ; Point to next char
  110.     jmp        s @@DP_Scan_it        ; check again...
  111.  
  112. @@DP_Got_len:
  113.  
  114.     jcxz    @No_Print            ; Don't Print if empty
  115.  
  116.     mov        BX, 1                ; 1= DOS Handle for Display
  117.     mov        AH, 40h                ; Write Text Function
  118.     int        21h                    ; Call DOS to do it
  119.  
  120. @No_Print:
  121.     mov        AX, SEG DGROUP        ; Restore DGroup
  122.     mov        DS, AX
  123.  
  124.     mov        DX, o CR_LF            ; Get Addr of CR/LF pair
  125.     mov        CX, 2                ; 2 Characters to Write        
  126.     mov        BX, 1                ; 1= DOS Handle for Display
  127.  
  128.     mov        AH, 40h                ; Write Text Function
  129.     int        21h                    ; Call DOS to do it
  130.  
  131.     cld                            ; Reset Direction Flag        
  132.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  133.     ret        4                    ; Exit & Clean Up Stack
  134.  
  135. DOS_PRINT     ENDP
  136.  
  137.  
  138. ;===========================================
  139. ;void far pascal dos_prints (char far *Text)
  140. ;===========================================
  141. ; Print Text Directly to DOS console 
  142. ; without a trailing CR/LF
  143. ;
  144.  
  145.     PUBLIC    DOS_PRINTS
  146.  
  147. DOS_PRINTS     PROC     FAR
  148.  
  149.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  150.     mov        BP, SP                ; Set up Stack Frame
  151.  
  152.     lds     DX, [BP].DP_Text    ; Get Addr of Text$ descriptor
  153.  
  154.     ; Compute Length of string
  155.  
  156.     CLR        CX                    ; Length = 0
  157.     mov        SI, DX                ; DS:SI = String data
  158.  
  159. @@DPS_Scan_it:
  160.     
  161.     cmp        b [SI], 0            ; Null Byte found?
  162.     je        @@DPS_Got_Len        ; exit loop if so
  163.  
  164.     inc        CX                    ; Len++
  165.     inc        SI                    ; Point to next char
  166.     jmp        s @@DPS_Scan_it        ; check again...
  167.  
  168. @@DPS_Got_len:
  169.  
  170.     jcxz    @DPS_Exit            ; Don't Print if empty
  171.  
  172.     mov        BX, 1                ; 1= DOS Handle for Display
  173.     mov        AH, 40h                ; Write Text Function
  174.     int        21h                    ; Call DOS to do it
  175.  
  176. @DPS_Exit:
  177.     cld                              ; Reset Direction Flag        
  178.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  179.     ret        2                    ; Exit & Clean Up Stack
  180.  
  181. DOS_PRINTS     ENDP
  182.  
  183.  
  184. ;=========================================
  185. ;void far pascal set_video_mode (int Mode)
  186. ;=========================================
  187. ;
  188. ; Sets the Video Mode through the BIOS
  189. ;
  190.  
  191.     PUBLIC    SET_VIDEO_MODE
  192.  
  193. SVM_Stack    STRUC
  194.                 DW    ?x4    ; DI, SI, DS, BP
  195.                 DD    ?    ; Caller
  196.     SVM_Mode    DB    ?,? ; Desired Video Mode
  197. SVM_Stack    ENDS
  198.  
  199.  
  200. SET_VIDEO_MODE    PROC    FAR
  201.  
  202.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  203.     mov        BP, SP                ; Set up Stack Frame
  204.  
  205.     CLR        AH                    ; Function 0
  206.     mov        AL, [BP].SVM_Mode    ; Get Mode #
  207.  
  208.     int        10H                    ; Change Video Modes
  209.  
  210. @SVM_Exit:
  211.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  212.     ret        2                    ; Exit & Clean Up Stack
  213.  
  214. SET_VIDEO_MODE    ENDP
  215.  
  216.  
  217. ;===================================
  218. ;int far pascal scan_keyboard (void)
  219. ;===================================
  220. ;
  221. ; Function to scan keyboard for a pressed key
  222. ;
  223.  
  224.     PUBLIC    SCAN_KEYBOARD
  225.  
  226. SCAN_KEYBOARD    PROC    FAR
  227.  
  228.     PUSHx    BP, DS, SI, DI        ; Preserve Important Registers
  229.  
  230.     mov        AH, 01H                ; Function #1
  231.     INT        16H                    ; Call Keyboard Driver
  232.     JZ        @SK_NO_KEY            ; Exit if Zero flag set
  233.  
  234.     mov        AH,    00H                ; Remove Key from Buffer
  235.     INT        16H                    ; Get Keycode in AX
  236.  
  237.     OR        AL, AL                ; Low Byte Set (Ascii?)
  238.     JZ        @SK_Exit            ; if not, it's a F-Key
  239.  
  240.     CLR        AH                    ; Clear ScanCode if Ascii
  241.     JMP        s @SK_Exit            ; Return Key in AX
  242.  
  243. @SK_NO_KEY:
  244.     CLR        AX                    ; Return Nil (no Keypress)
  245.  
  246. @SK_Exit:
  247.     cld                            ; Reset Direction Flag        
  248.     POPx    DI, SI, DS, BP        ; Restore Saved Registers
  249.     ret                            ; Exit & Clean Up Stack
  250.  
  251. SCAN_KEYBOARD    ENDP
  252.  
  253.  
  254. ;========================================
  255. ;int far pascal random_int (int MaxValue)
  256. ;========================================
  257. ;
  258. ; Returns a pseudo-random number in the range of (0.. MaxInt-1)
  259. ;
  260.  
  261.  
  262.     PUBLIC    RANDOM_INT
  263.  
  264. RI_Stack    STRUC
  265.                 DW    ?    ; BP
  266.                 DD    ?    ; Caller
  267.     RI_MaxVal    DW    ?    ; Maximum Value to Return + 1
  268. RI_Stack    ENDS
  269.  
  270.  
  271. RANDOM_INT    PROC    FAR
  272.  
  273.     push    BP                    ; Preserve Important Registers
  274.     mov        BP, SP                ; Set up Stack Frame
  275.  
  276.        CLR        BX                    ; BX is the data index
  277.     CLR        CX                      ; CX is the accumulator
  278.  
  279. REPT 3
  280.       mov        AX, RND_Seed[BX]    ; load the initial seed
  281.     mul        RND_Mult[BX]        ; multiply it
  282.     div        RND_ModV[BX]        ; and obtain the Mod value
  283.     mov        RND_Seed[BX], DX    ; save that for the next time
  284.  
  285.     add        CX, DX                ; add it into the accumulator
  286.     inc        BX
  287.     inc        BX                  ; point to the next set of values
  288. ENDM
  289.  
  290.     mov        AX, CX                ; AX = Random #
  291.     CLR        DX                    ; DX = 0
  292.     div        [BP].RI_MaxVal        ; DX = DX:AX / MAxVal Remainder
  293.  
  294.     mov        AX, DX
  295.  
  296.     pop        BP                    ; Restore BP
  297.     ret        2                    ; back to BASIC with AX holding the result
  298.  
  299. RANDOM_INT    ENDP
  300.  
  301.  
  302. ;==================================
  303. ;void far pascal init_random (void)
  304. ;==================================
  305. ;
  306. ; Scrambles the psuedo-random number sequence
  307. ; (XOR's the seed value with the timer)
  308. ;
  309.  
  310.     PUBLIC    INIT_RANDOM
  311.  
  312. INIT_RANDOM    PROC    FAR
  313.  
  314.     CLR        AX                    ; Segment = 0000
  315.     mov        ES, AX
  316.     mov        AX, ES:[046Ch]      ; Get Timer Lo Word
  317.  
  318.     xor        RND_Seed, AX        ; Scramble 1st Seed
  319.  
  320.     ret                            ; Exit & Clean Up Stack
  321.  
  322. INIT_RANDOM    ENDP
  323.  
  324. ;=========================================
  325. ;int far pascal int_sqr (int X, int Round)
  326. ;=========================================
  327. ;
  328. ; Returns the Integer Square Root of (X)
  329. ; Round allows the return value to be rounded to the 
  330. ; nearest integer value by passing 0x80.  Passing 0
  331. ; return the Integer Portion only.  The rounding amound is
  332. ; a number from 0 to 1 multiplied by 256, thus 
  333. ; 0.5 * 0x100 = 0x80!
  334. ;
  335.  
  336. ISQ_Stack    STRUC
  337.                     DW    ?,?    ; BP, DI
  338.                     DD    ?    ; Caller
  339.     ISQ_Round        DW    ?    ; Amount to Round Result * 256
  340.     ISQ_X            DW    ?    ; "X"
  341. ISQ_Stack    ENDS
  342.  
  343.     PUBLIC    INT_SQR
  344.  
  345. INT_SQR        PROC    FAR
  346.  
  347.     PUSHx   BP, DI                ; Save BP
  348.     mov     BP, SP                ; Set up Stack Frame
  349.  
  350.      xor     AX, AX                ; {xor eax,eax}
  351.     xor     DX, DX                ; {xor edx,edx}
  352.     mov     DI, [BP].ISQ_X        ; {mov edi,x}
  353.  
  354.     mov     CX, 16                ; {mov cx, 32}
  355.  
  356. @ISQ_L:
  357.  
  358.     shl     DI, 1                ; {shl edi,1}
  359.     rcl     DX, 1                ; {rcl edx,1}
  360.     shl     DI, 1                ; {shl edi,1}
  361.     rcl     DX, 1                ; {rcl edx,1}
  362.     shl     AX, 1                ; {shl eax,1}
  363.     mov     BX, AX                ; {mov ebx,eax}
  364.     shl     BX, 1                ; {shl ebx,1}
  365.     inc     BX                     ; {inc ebx}
  366.     cmp     DX, BX                ; {cmp edx,ebx}
  367.     jl         @ISQ_S
  368.  
  369.       sub     DX, BX                ; {sub edx,ebx}
  370.     inc     AX                     ; {inc eax}
  371.  
  372. @ISQ_S: 
  373.     loop     @ISQ_L
  374.  
  375.       add     ax, [BP].ISQ_Round    ; {add eax,$00008000}  
  376.                                 ; {*round* result in hi word: ie. +0.5}
  377.     shr     ax, 8                ; {shr eax,16}  {to ax (result)}
  378.  
  379.     POPx    DI, BP                ; Restore Registers    
  380.     ret        4                    ; Exit
  381.  
  382. INT_SQR        ENDP
  383.  
  384. ;=================================
  385. ;int far pascal timer_count (void)
  386. ;=================================
  387. ;
  388. ; Returns the current timer value as an integer/long integer
  389. ;
  390.  
  391.     PUBLIC  TIMER_COUNT
  392.  
  393. TIMER_COUNT      PROC    FAR
  394.  
  395.     CLR        AX                    ; Segment = 0000
  396.     mov        ES, AX
  397.     mov        AX, ES:[046Ch]      ; Get Timer Lo Word
  398.     mov        DX, ES:[046Eh]        ; Get Timer Hi Word
  399.     ret                            ; Exit & Clean Up Stack
  400.  
  401. TIMER_COUNT      ENDP
  402.  
  403.  
  404.     END
  405.